package com.blue.encryption;

import org.apache.commons.codec.binary.Hex;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @Description: MessageDigest信息摘要：
 *      对目标内容通过摘要算法（hash函数）计算出一个结果（推荐使用org.apache.commons.codec.digest.DigestUtils）
 *      参考资料
 *      https://blog.csdn.net/mn960mn/article/details/78172047
 *      全部支持的算法见官方文档：
 *  * 	    https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest
 *  *      Security.getAlgorithms("MessageDigest").forEach(System.out::println);提供的信息签名算法
 *      注：SHA和SHA-1一致两个可以替换
 *      BASE64和HEX只是对摘要结果的不同编码显示，与加密无关。
 * @Auther:  wellcome to javaweb.io
 * @Date: 2019/1/22 17:39
 */
public class MessageDigestUtil {
    public static final String MESSAGE_DIGEST_KEY_MD2="MD2";
    public static final String MESSAGE_DIGEST_KEY_MD5="MD5";
    public static final String MESSAGE_DIGEST_KEY_SHA="SHA";
    public static final String MESSAGE_DIGEST_KEY_SHA_1="SHA-1";
    public static final String MESSAGE_DIGEST_KEY_SHA_224="SHA-224";
    public static final String MESSAGE_DIGEST_KEY_SHA_256="SHA-256";
    public static final String MESSAGE_DIGEST_KEY_SHA_384="SHA-384";
    public static final String MESSAGE_DIGEST_KEY_SHA_512="SHA-512";
    public static final int MESSAGE_DIGEST_ENCODE_BASE64=1;
    public static final int MESSAGE_DIGEST_ENCODE_HEX=2;

    /**
     * 数字签名核心
     * @param algorithm
     * @param bytes
     * @return 把摘要后的结果转换成十六进制的字符串（也可以使用Base64进行编码）
     */
    private static String messageDigest(String algorithm,byte[] bytes,int encodeModel){
        MessageDigest messageDigest= null;
        String messageDigestStr="";
        try {
            messageDigest = MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        byte[] digest=messageDigest.digest(bytes);
        switch (encodeModel){
            case MESSAGE_DIGEST_ENCODE_BASE64:
                messageDigestStr=Base64.getEncoder().encodeToString(digest);
                break;
            case MESSAGE_DIGEST_ENCODE_HEX:
                messageDigestStr=Hex.encodeHexString(digest);
                break;
            default:
                //默认使用16位Hex
                messageDigestStr=Hex.encodeHexString(digest);
        }
        return messageDigestStr;
    }

    /**
     * 获取md5摘要
     * @param content 字符串
     * @param model
     * @return
     */
    public static String getMd5Digest(String content,int model){
        String md5DigestStr="";
        try {
            byte[] bytes=content.getBytes("UTF-8");
            //获取md5
            md5DigestStr=getMD5(bytes,model);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return md5DigestStr;
    }

    /**
     * 获取SHA摘要
     * @param content 字符串
     * @param model
     * @return
     */
    public static String getSHADigest(String content,int model){
        String shaDigestStr="";
        try {
            byte[] bytes=content.getBytes("UTF-8");
            shaDigestStr=messageDigest(MESSAGE_DIGEST_KEY_SHA,bytes,model);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return shaDigestStr;
    }

    /**
     * 获取SHA1摘要
     * @param content 字符串
     * @param model
     * @return
     */
    public static String getSHA1Digest(String content,int model){
        String sha1DigestStr="";
        try {
            byte[] bytes=content.getBytes("UTF-8");
            sha1DigestStr=messageDigest(MESSAGE_DIGEST_KEY_SHA_1,bytes,model);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return sha1DigestStr;
    }

    /**
     *通用的md5摘要
     * @param bytes
     * @param model
     * @return
     */
    public static String getMD5(byte[] bytes,int model){
       String  md5DigestStr=messageDigest(MESSAGE_DIGEST_KEY_MD5,bytes,model);
       return md5DigestStr;
    }

    /**
     *通用的sha摘要
     * @param bytes
     * @param model
     * @return
     */
    public static String getSHA(byte[] bytes,int model){
        String  shaDigestStr=messageDigest(MESSAGE_DIGEST_KEY_SHA,bytes,model);
        return shaDigestStr;
    }

    /**
     * 例如：maven下载的jar包和pom文件都有一个对应的sha1文件,以本例中使用的commons-codec验证一下
     * @param args
     */
    public static void main(String[] args) {
        try {
            byte[] bytes= Files.readAllBytes(Paths.get("D:/mavenRep/commons-codec/commons-codec/1.10/commons-codec-1.10.jar"));
            //4b95f4897fa13f2cd904aee711aeafc0c5295cd8对比和commons-codec-1.10.jar.sha1文件中的值一致
            System.out.println(getSHA(bytes,MESSAGE_DIGEST_ENCODE_HEX));
            byte[] bytes1= Files.readAllBytes(Paths.get("D:/mavenRep/commons-codec/commons-codec/1.10/commons-codec-1.10.pom"));
            //44b9477418d2942d45550f7e7c66c16262062d0e对比和commons-codec-1.10.pom.sha1文件中的值一致
            System.out.println(getSHA(bytes1,MESSAGE_DIGEST_ENCODE_HEX));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
